package learm.pers.studypdf.pdf.controller;


import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
import io.micrometer.common.util.StringUtils;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import learm.pers.studypdf.pdf.dto.SynthesisDTO;
import learm.pers.studypdf.pdf.dto.SynthesisFileDTO;
import learm.pers.studypdf.pdf.dto.ZTenantFileDTO;
import learm.pers.studypdf.pdf.utils.CommonUtil;
import learm.pers.studypdf.pdf.utils.FileUtils;
import lombok.extern.slf4j.Slf4j;

import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Value;

import org.springframework.mock.web.MockMultipartFile;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import java.io.*;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.List;

/**
 * @author Zhongwen Ai
 * @crate 2020-03-20-14:31
 * @description
 */
@Slf4j
@RestController
@RequestMapping("/uploadFile")
public class UploadFileController {

    @Value("${upload.attachmentDir}")
    private String attachmentDir;

    @Value("${customer.app-name}")
    private String attachmentUrl;


    @RequestMapping(value = "/upload/{uploadPath}", method = RequestMethod.POST)
    public String upload(@RequestParam("file") MultipartFile files, @PathVariable() String uploadPath, HttpServletRequest request, HttpServletResponse response) throws IOException {
        JSONObject json=new JSONObject();
        response.setCharacterEncoding("utf-8");
        String msg = "添加成功";
        String flag = "success";
        log.info("-------------------开始调用上传文件upload接口-------------------");
        try{
            Calendar cal = Calendar.getInstance();
            int year = cal.get(Calendar.YEAR);
            int month = cal.get(Calendar.MONTH )+1;
            String fileUrl = attachmentUrl+"/"+uploadPath+"/"+year+"/"+month+"/";
            String fileDir = attachmentDir+"/"+uploadPath+"/"+year+"/"+month+"/";
            // 判断文件是否为空
            if (!files.isEmpty()) {
                // 转存文件
                FileUtils.createDirectory(fileDir);
                // 获取文件名
                String name = files.getOriginalFilename();
                //判断是否为IE浏览器的文件名，IE浏览器下文件名会带有盘符信息
                int unixSep = name.lastIndexOf('/'); // Check for Unix-style path
                int winSep = name.lastIndexOf('\\');// Check for Windows-style path
                int pos = (winSep > unixSep ? winSep : unixSep); // Cut off at latest possible point
                if (pos != -1)  {
                    name = name.substring(pos + 1);
                }
                String filePath = fileDir +  name;
                File newFile = FileUtils.getAvailableFile(filePath,0);
                files.transferTo(newFile);
                json.put("id", newFile.getAbsolutePath());
                json.put("url", fileUrl+ newFile.getName());
            }
        }catch(Exception e){
            flag = "error";
            msg="添加失败";
        }
        log.info("-------------------结束调用上传文件upload接口-------------------");
        json.put("msg", msg);
        json.put("flag", flag);
//        return BuildJsonOfObject.buildJsonOfJsonObject(json);
        return JSONObject.toJSONString(json);

    }


    /**
     * 批量删除文件管理
     */
    @PostMapping(value = "/delete")
    public String deleteFile(String id) {
        JSONObject json=new JSONObject();
        String msg = "删除成功";
        String flag = "success";
        if(!CommonUtil.isNotEmpty(id) || !FileUtils.delFile(id)){
            flag = "error";
            msg="删除失败";
        }
        json.put("flag", flag);
        json.put("msg", msg);
        return JSONObject.toJSONString(json);
    }



    /**
     * 新的删除文件 删除文件、记录逻辑删除
     */
    @PostMapping(value = "/delFile")
    public String delFile(String id, String filePath) {
        JSONObject json=new JSONObject();
        String msg = "删除成功";
        String flag = "success";
        if (StringUtils.isBlank(id) || StringUtils.isBlank(filePath)) {
            flag = "error";
            msg="删除失败";
        } else {
            FileUtils.delFile(filePath);
//            commFileService.removeById(id);
        }
        json.put("flag", flag);
        json.put("msg", msg);
        return JSONObject.toJSONString(json);
    }

	/*private byte[] inputStreamToByte(InputStream is) throws IOException {
		ByteArrayOutputStream bAOutputStream = new ByteArrayOutputStream();
		int ch;
		while ((ch = is.read()) != -1) {
			bAOutputStream.write(ch);
		}
		byte data[] = bAOutputStream.toByteArray();
		bAOutputStream.close();
		return data;
	}*/

    @RequestMapping(value = "/uploadservlet", method = RequestMethod.POST, produces = "text/html;charset=utf-8")
    protected String uploadServlet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        JSONObject json=new JSONObject();
        response.setCharacterEncoding("utf-8");
        String msg = "添加成功";
        log.info("-------------------开始调用上传文件uploadservlet接口-------------------");
        try {
            if (request instanceof MultipartHttpServletRequest) {
                MultipartHttpServletRequest mr = (MultipartHttpServletRequest) request;
                List<MultipartFile> multipartFile = mr.getFiles("myfile");
                if (null != multipartFile && !multipartFile.isEmpty()) {
                    MultipartFile file = multipartFile.get(0);
                    String name = file.getOriginalFilename();
                    String path = this.getClass().getClassLoader().getResource("/").getPath();
                    int index = path.indexOf("Shopping");
                    path = path.substring(0, index + "Shopping".length()) + "/WebContent/resources/upload/";
                    path = path + File.separator + name;
                    File uploadFile = new File(path);
                    if(FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(uploadFile))>0)
                    {
                        json.put("path",path);
                    }

                }
            }
        } catch (Exception e) {
            msg = "上传失败";
        }
        log.info("-------------------结束调用上传文件uploadservlet接口-------------------");
        json.put("msg", msg);
//        return BuildJsonOfObject.buildJsonOfJsonObject(json);
        return JSONObject.toJSONString(json);
    }


    /**
     * 下载附件
     * @param path
     * @param response
     * @return
     */
    @RequestMapping(value = "/download")
    public void download(String path, HttpServletResponse response) {
//        if(redissonLockClient.tryLock(GlobalConstant.QT_ORDER_LOCK_KEY + path, GlobalConstant.REDIS_DETAIL_EXPIRED_TIME)) {
            try {
                path = path.replace(attachmentUrl,attachmentDir);//windows本地库路径转换
                // path是指欲下载的文件的路径。
                File file = new File(path);
                // 取得文件名。
                String filename = file.getName();
                // 取得文件的后缀名。
                String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();

                // 以流的形式下载文件。
                InputStream fis = new BufferedInputStream(new FileInputStream(path));
                byte[] buffer = new byte[fis.available()];
                fis.read(buffer);
                fis.close();
                // 清空response
                response.reset();
                // 设置response的Header
                response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes(),"ISO-8859-1"));
                response.addHeader("Content-Length", "" + file.length());
                OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
                response.setContentType("application/octet-stream");
                toClient.write(buffer);
                toClient.flush();
                toClient.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                log.info("-------------------下载文件了-------------------" + path);
            }
    }


    @RequestMapping(value = "previewImage")
    public void previewImage(String filePath , HttpServletResponse response){
        filePath = filePath.replace(" ", "");
        FileInputStream is =null;
        OutputStream out =null;
        try {
            filePath = URLDecoder.decode(filePath,"utf-8");//中文乱码转码
            filePath = filePath.replace(attachmentUrl,attachmentDir);//本地库路径转换
            File file = new File(filePath);
            if (file.exists()) {
                is = new FileInputStream(file);
                int size = is.available();
                byte[] data = new byte[size];
                is.read(data);
                //response.setContentType("image/*");
                out = response.getOutputStream();
                out.write(data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(out!=null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 进行合并文件 成pdf
     * @param dto
     * @return
     */
    @PostMapping("/doSynthesis")
    public Boolean doSynthesis(@RequestBody SynthesisDTO dto, HttpServletRequest request, HttpServletResponse response) {

        try {
            String lj = "";
            if(null != dto && CollectionUtil.isNotEmpty(dto.getFileList())){
                List<SynthesisFileDTO> fileList = dto.getFileList();

                Calendar cal = Calendar.getInstance();
                int year = cal.get(Calendar.YEAR);
                int month = cal.get(Calendar.MONTH )+1;
                String fileDir = attachmentDir+"/other/"+year+"/"+month+"/";

                String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
                String pdfName = uuid + ".pdf";

                Document document = new Document();
                PdfWriter.getInstance(document,new FileOutputStream(fileDir + pdfName));
                //2 open document
                document.open();
                document.add(new Chunk("高新区公租房"));
                ArrayList<String> pdfList = new ArrayList<>();
                for (int i = 0; i < fileList.size(); i++) {
                    SynthesisFileDTO synthesisFileDTO = fileList.get(i);

                    if (!new File(synthesisFileDTO.getAbsolutePath()).exists()) {
                        continue;
                    }
                    String extendName = FileUtils.getExtendName(synthesisFileDTO.getFileName());
                    String hz = "jpg,png,jpeg,JPG,PNG,JPEG";
                    if(hz.contains(extendName)){
                        //3.添加image
                        Image image = Image.getInstance(synthesisFileDTO.getAbsolutePath());
                        //image.scaleAbsolute(PageSize.A4.rotate());

                        //region 图片自适应
                        Rectangle defaultPageSize = PageSize.A4.rotate();
                        float pageWidth = defaultPageSize.getWidth()-330;
                        float pageHeight = defaultPageSize.getHeight()-20;

                        if (image.getScaledWidth() > pageWidth || image.getScaledHeight() > pageHeight)
                        {
                            image.scaleAbsolute(pageWidth, pageHeight);
                        }


                        //image.scaleAbsolute(500, 400);
                        document.add(image);
                    }else{
                        pdfList.add(synthesisFileDTO.getAbsolutePath());
                        continue;
                    }
                }

                //4. 关闭document
                document.close();

                lj = fileDir + pdfName;
                if(CollectionUtil.isNotEmpty(pdfList)){
                    pdfList.add(fileDir + pdfName);
                    String uuid1 = UUID.randomUUID().toString().trim().replaceAll("-", "");

                    String newlj = fileDir + uuid1 + ".pdf";
                    mergePdfFile(pdfList,newlj);
                    lj = newlj;
                }
            }
            if(StringUtils.isNotBlank(lj)){
                File file = new File(lj);
                MultipartFile multipartFile = getMultipartFile(file);


                String upload = upload(multipartFile, dto.getUploadPath(), request, response);
                JSONObject jsonObject = JSON.parseObject(upload);
                String absolutePath = jsonObject.getString("id");
                String filePath = jsonObject.getString("url");
                String size = FileUtils.getFileSize(filePath.replace(attachmentUrl, attachmentDir));
                String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
                String exstendName = FileUtils.getExtendName(filePath);

                ArrayList<ZTenantFileDTO> TTenantFileList = new ArrayList<>();

                ZTenantFileDTO tTenantFile = new ZTenantFileDTO();
                tTenantFile.setFileName(fileName)
                        .setFilePath(filePath)
                        .setFileUrl(filePath)
                        .setExstendName(exstendName)
                        .setFileSize(size)
                        .setAbsolutePath(absolutePath);
                TTenantFileList.add(tTenantFile);


                //return Result.success().data(TTenantFileList);
                return true;
            }



            //return Result.error();
            return false;

        } catch (Exception e) {
            e.printStackTrace();
            //return Result.error();
            return false;
        }finally {
            if(null != dto && CollectionUtil.isNotEmpty(dto.getFileList())){
                List<SynthesisFileDTO> fileList = dto.getFileList();
                for (int i = 0; i < fileList.size(); i++) {
                    SynthesisFileDTO synthesisFileDTO = fileList.get(i);
                    FileUtils.delFile(synthesisFileDTO.getAbsolutePath());
                }
            }

        }
    }



    /**
     * 合并PDF文件
     * @param sourceFilePaths 需要合并的PDF文件路径列表
     * @param destFilePath 合并后的新文件
     */
    public static void mergePdfFile(List<String> sourceFilePaths, String destFilePath) {
        if (sourceFilePaths == null || sourceFilePaths.isEmpty() || destFilePath == null) {
            return;
        }
        Document document = null;
        PdfCopy copy = null;
        OutputStream os = null;
        try {
            // 创建合并后的新文件的目录
            Path dirPath = Paths.get(destFilePath.substring(0, destFilePath.lastIndexOf("/")));
            Files.createDirectories(dirPath);

            os = new BufferedOutputStream(new FileOutputStream(new File(destFilePath)));
            document = new Document(new PdfReader(sourceFilePaths.get(0)).getPageSize(1));
            copy = new PdfCopy(document, os);
            document.open();
            for (String sourceFilePath : sourceFilePaths) {
                // 如果PDF文件不存在，则跳过
                if (!new File(sourceFilePath).exists()) {
                    continue;
                }

                // 读取需要合并的PDF文件
                PdfReader reader = new PdfReader(sourceFilePath);
                // 获取PDF文件总页数
                int n = reader.getNumberOfPages();
                for (int j = 1; j <= n; j++) {
                    document.newPage();
                    PdfImportedPage page = copy.getImportedPage(reader, j);
                    copy.addPage(page);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (copy != null) {
                try {
                    copy.close();
                } catch (Exception ex) {
                    /* ignore */
                }
            }
            if (document != null) {
                try {
                    document.close();
                } catch (Exception ex) {
                    /* ignore */
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (Exception ex) {
                    /* ignore */
                }
            }
        }
    }


    private MultipartFile getMultipartFile(File file){
        FileInputStream fileInputStream = null;
        MultipartFile multipartFile = null;
        try {
            fileInputStream = new FileInputStream(file);
            multipartFile = new MockMultipartFile(file.getName(),file.getName(),
                    ContentType.APPLICATION_OCTET_STREAM.toString(),fileInputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return multipartFile;
    }





}
